package com.xiaolin.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaolin.admin.exception.ServiceException;
import com.xiaolin.admin.mapper.SysOrganizationMapper;
import com.xiaolin.admin.mapper.SysUserMapper;
import com.xiaolin.admin.model.dto.CurrentUser;
import com.xiaolin.admin.model.dto.SysOrganizationTree;
import com.xiaolin.admin.model.entity.SysOrganization;
import com.xiaolin.admin.model.entity.SysUser;
import com.xiaolin.admin.service.SysOrganizationService;
import com.xiaolin.admin.utils.ContextUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织架构表 服务实现类
 * </p>
 *
 * @author xiaolin
 * @since 2024-07-12
 */
@Service
public class SysOrganizationServiceImpl extends ServiceImpl<SysOrganizationMapper, SysOrganization> implements SysOrganizationService {
    @Autowired
    private SysOrganizationMapper organizationMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private ContextUtil contextUtil;


    @Override
    public List<SysOrganizationTree> getOrgTree(SysOrganization organization) {
        List<SysOrganizationTree> organizationTrees = new ArrayList<>();
        List<SysOrganization> organizations = organizationMapper.getOrgList(organization);
        if (!CollectionUtils.isEmpty(organizations)) {
            List<Integer> allIds = organizations.stream().map(SysOrganization::getId).collect(Collectors.toList());
            for (SysOrganization org : organizations) {
                // 找出第一层级的组织
                if (!allIds.contains(org.getPid())) {
                    SysOrganizationTree organizationTree = new SysOrganizationTree();
                    BeanUtils.copyProperties(org, organizationTree);
                    // 构建组织数
                    organizationTree.setChildren(buildOrgTree(organizations, org.getId()));
                    organizationTrees.add(organizationTree);
                }
            }
        }
        return organizationTrees;
    }

    private List<SysOrganizationTree> buildOrgTree(List<SysOrganization> organizations, Integer pid) {
        List<SysOrganizationTree> organizationTrees = null;
        for (SysOrganization organization : organizations) {
            if (pid.equals(organization.getPid())) {
                if (CollectionUtils.isEmpty(organizationTrees)) {
                    organizationTrees = new ArrayList<>();
                }
                SysOrganizationTree organizationTree = new SysOrganizationTree();
                BeanUtils.copyProperties(organization, organizationTree);
                organizationTree.setChildren(buildOrgTree(organizations, organizationTree.getId()));
                organizationTrees.add(organizationTree);
            }
        }
        return organizationTrees;
    }

    /**
     * 校验部门唯一性
     *
     * @param organization
     * @return
     */
    @Override
    public void checkUnique(SysOrganization organization) {
        long count = organizationMapper.selectCount(new LambdaQueryWrapper<SysOrganization>()
                .eq(SysOrganization::getPid, organization.getPid())
                .eq(SysOrganization::getOrgName, organization.getOrgName())
                .ne(Objects.nonNull(organization.getId()), SysOrganization::getId, organization.getId()));
        if (count > 0) {
            ServiceException.error("兄弟部门名称重复了");
        }
    }

    @Override
    public void checkOrgRelation(Integer orgId) {
        long count = organizationMapper.selectCount(new LambdaQueryWrapper<SysOrganization>().eq(SysOrganization::getPid, orgId));
        if (count > 0) {
            ServiceException.error("该部门有下属部门，无法删除");
        }
    }

    @Override
    public void checkUserRelation(Integer orgId) {
        long count = userMapper.selectCount(new LambdaQueryWrapper<SysUser>().eq(SysUser::getOrgId, orgId));
        if (count > 0) {
            ServiceException.error("该部门关联了用户，无法删除");
        }
    }

    @Override
    public boolean addOrg(SysOrganization organization) {
        CurrentUser user = contextUtil.getCurrentUser();
        // 校验部门唯一性
        checkUnique(organization);
        organization.setCreator(user.getId());
        organization.setUpdator(user.getId());
        organizationMapper.insert(organization);
        return true;
    }

    @Override
    public SysOrganization getOrg(Integer id) {
        return organizationMapper.selectById(id);
    }

    @Override
    public boolean updateOrg(SysOrganization organization) {
        // 校验部门唯一性
        checkUnique(organization);
        organizationMapper.updateById(organization);
        return true;
    }

    @Override
    public boolean deleteOrg(Integer id) {
        // 校验部门是否有子部门
        checkOrgRelation(id);
        // 校验部门与用户是否关联
        checkUserRelation(id);
        organizationMapper.deleteById(id);
        return true;
    }

    @Override
    public List<Integer> getUserOrgDataPerms() {
        CurrentUser currentUser = contextUtil.getCurrentUser();
        return organizationMapper.getUserOrgDataPerms(currentUser.getId());
    }
}
